﻿using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Http;
using SX.Repository;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;
using SX.Utils;
using SmartSql.Abstractions;

namespace SX.Services
{
    public class UserService
    {
        private readonly IHttpContextAccessor _contextAccessor;
        private HttpContext _context;
        public HttpContext Context
        {
            get
            {
                var context = _context ?? _contextAccessor?.HttpContext;
                if (context == null)
                {
                    throw new InvalidOperationException("HttpContext must not be null.");
                }
                return context;
            }
            set
            {
                _context = value;
            }
        }

        private readonly IUsersRepository _usersRepository;
        private readonly ILogRepository _logRepository;
        private readonly ISmartSqlMapper _smartSqlMapper;

        public UserService(IHttpContextAccessor contextAccessor,
            ISmartSqlMapper smartSqlMapper ,
            IUsersRepository usersRepository, ILogRepository logRepository) {
            _contextAccessor = contextAccessor;
            _smartSqlMapper = smartSqlMapper;
            _usersRepository = usersRepository;
            _logRepository = logRepository;
        }

        /// <summary>
        /// 用户名密码登录
        /// </summary>
        /// <param name="userName">Name of the user.</param>
        /// <param name="password">The password.</param>
        /// <returns></returns>
        public async Task<LoginResult> PasswordLogin(string userName, string password) {
           var userList =    _usersRepository.Query(new { username = userName, user_status = 0 }).ToList();
            if (!userList.Any() || userList.Count() >1)
            {
                return LoginResult.Failed;
            }
           var claims = new List<Claim> {
                new Claim("userid", userList[0].user_Id.ToString()),
               new Claim("realname",userList[0].realname)
            };
            if (userList[0].is_sup == 1)
            {
                claims.Add(new Claim("is_sup", "1"));
            }
            var claimsIdentity = new ClaimsIdentity(
                claims,
                CookieAuthenticationDefaults.AuthenticationScheme);
            // 更新登录时间
            _usersRepository.DyUpdate(new { user_id = userList[0].user_Id, last_login_time = DateTime.Now, last_login_ip = Context.GetUserIp()});
            await Context.SignInAsync(
                CookieAuthenticationDefaults.AuthenticationScheme,
                new ClaimsPrincipal(claimsIdentity),
                new AuthenticationProperties
                {
                    IsPersistent = true,
                    ExpiresUtc = DateTime.UtcNow.AddDays(7)
                });
            return LoginResult.Success;
        }

        /// <summary>
        /// 退出
        /// </summary>
        /// <returns></returns>
        public async Task SignOutAsync()
        {
            await Context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
        }
        /// <summary>
        /// 获取用户模块
        /// </summary>
        /// <param name="userId">The user identifier.</param>
        /// <param name="menu_position">The menu position.</param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public object GetUserModules(long userId, int menu_position)
        {
            int is_sup = _usersRepository.("select is_sup from sys_users where user_id = @user_id ")
                 .Parameter("user_id", userId)
                 .QuerySingle<int>();
            List<dynamic> menuList;
            if (is_sup == 1)
            {
                menuList = GetList<dynamic>(new { menu_type = 0, menu_position = menu_position, menu_status = 0, parent_id = 0 }, "menu_id,name,icon,url,parent_id,sort", "sort");
            }
            else
            {
                // 只获取菜单
                menuList = GetListBySql<dynamic>(@" select menu_id,name,icon,url,parent_id,sort
                from sys_menus where menu_type = 0 and menu_position =@menu_position and menu_status = 0 and parent_id = 0 and menu_id in (select a.auth_id 
                    from sys_user_role r join sys_auth a on a.obj_type =0 and a.auth_type = 0   and r.role_id =a.obj_id 
                    where r.user_id =@user_id
                    union all 
                    select a.auth_id 
                    from  sys_auth a    
                    where  a.obj_type =1 and a.auth_type = 0  and a.obj_id  =@user_id
                ) order by sort, menu_id ", new { user_id = userId, menu_position = menu_position });
            }
            List<object> result = GetChilds(0, menuList);
            return result;
        }
    }
}
